package com.tuanzhang.zhw.rpc.spring;

import com.tuanzhang.zhw.rpc.config.consumer.ConsumerConfig;
import com.tuanzhang.zhw.rpc.config.consumer.RpcClientConfig;
import com.tuanzhang.zhw.rpc.config.provider.ProviderConfig;
import com.tuanzhang.zhw.rpc.register.zookeeper.RpcRegistryProviderService;
import com.tuanzhang.zhw.rpc.spring.annotaion.RpcReference;
import com.tuanzhang.zhw.rpc.spring.annotaion.RpcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * 【zhw-rpc】 后置处理
 */
@Slf4j
@Component
public class RpcSpringBeanPostProcessor implements BeanPostProcessor {

    @Autowired
    private RpcClientConfig rpcClientConfig;
    @Autowired
    private RpcRegistryProviderService registryProviderService;

    /**
     * 初始化之后处理
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass().isAnnotationPresent(RpcService.class)) {
            log.info("【zhw-rpc】服务bean:{}", bean.getClass().getName());
            RpcService annotation = bean.getClass().getAnnotation(RpcService.class);
            //  注册到注册中心
            ProviderConfig config = new ProviderConfig();
            config.setInterfaceName(bean.getClass().getInterfaces()[0].getCanonicalName());
            config.setRef(bean);
            config.setVersion(annotation.version());
            registryProviderService.addProviderConfig(config);
        }
        return bean;
    }

    /**
     * 【zhw-rpc】 消费者代理注入
     * spring bean 初始化前注入 @RpcReference
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        Class<?> targetClass = bean.getClass();
        Field[] declaredFields = targetClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            RpcReference annotation = declaredField.getAnnotation(RpcReference.class);
            if (annotation == null) {
                continue;
            }
            // 1、 客户端代理
            ConsumerConfig<?> consumer = rpcClientConfig.getConsumer(declaredField.getType(), annotation.version());
            if (consumer == null) {
                throw new RuntimeException("【zhw-rpc】服务:{},没有找到提供者" + declaredField.getType().getName());
            }
            Object proxyInstance = consumer.getProxyInstance();
            declaredField.setAccessible(true);
            try {
                // 2、依赖注入
                declaredField.set(bean, proxyInstance);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return bean;
    }

}
